//
//  NetworkConnectivityManager.swift
//  NetworkConnectivity
//
//  Created by Aryaman Sharda on 2/18/22.
//

import Foundation
import Network
import RxSwift
import RxCocoa


public extension Notification.Name {
    static let connectivityStatus = Notification.Name(rawValue: "connectivityStatusChanged")
}

extension NWInterface.InterfaceType: CaseIterable {
    public static var allCases: [NWInterface.InterfaceType] = [
        .other,
        .wifi,
        .cellular,
        .loopback,
        .wiredEthernet
    ]
}

public struct NetworkStatus {
    public  var isShouQuan = false
    ///网络是否连接
    public var isConnected = true
    ///是否是重新连接
//    var isReconnect = false
    ///该网络是否是收费昂贵的 如:蜂窝或个人热点。
    public var isExpensive = false
    ///判断当前的网络
    public var currentConnectionType: NWInterface.InterfaceType?
}

public class NetworkMonitor {
    /**单例**/
    public static let shared = NetworkMonitor()
    private init() {
        monitor = NWPathMonitor()
    }
    
    ///判断用户是否首次授权,考虑到当前用户还没有授权的情况下,不能提前给用户错误网络判断
    private var isShouQuan : Bool {
        get{
            return UserDefaults.standard.bool(forKey: "isNetShouQuan")
        }
        set{
            UserDefaults.standard.set(newValue, forKey: "isNetShouQuan")
        }
    }
    
    private var status = NetworkStatus()
    private let monitor: NWPathMonitor
    ///监听是否重新连接
    public let reconnectObserable : PublishRelay<Bool> = PublishRelay()
    
    /// 监听网络
    public  let statusObserable:BehaviorRelay<NetworkStatus?> = BehaviorRelay(value: nil)
    ///监听的线程
    private let queue = DispatchQueue(label: "NetworkConnectivityMonitor")
    
    ///在appdelegate 里面开始监控
    public func startMonitoring() {
        monitor.pathUpdateHandler = { [weak self] path in
            guard let `self` = self else { return }
            
            //当 当前是原始是未连接状态,现在是变成连接状态后,就表示重新连接了
            let isReconnect = !self.status.isConnected && path.status != .unsatisfied
//            if  isReconnect {
//                MainThread {
//                    self.reconnectObserable.accept(isReconnect)
//                }
//            }
            
            self.status.isConnected = path.status != .unsatisfied
            
            self.status.isExpensive = path.isExpensive
            self.status.currentConnectionType = NWInterface.InterfaceType.allCases.filter { path.usesInterfaceType($0) }.first
            
            MainThread {
                self.statusObserable.accept( self.status)
                if isReconnect {
                    self.reconnectObserable.accept(isReconnect)
                }
            }
        }
        monitor.start(queue: queue)
    }
    
    public func checkNetworkPermissionStatus() -> Bool {
        // 检查当前应用程序是否被授权访问网络
        let isAuthorized = !NWPathMonitor().currentPath.availableInterfaces.isEmpty
        return isAuthorized
    }
    
    ///结束监控
    public func stopMonitoring() {
        monitor.cancel()
    }
}

